<template>
    <div class="popover" ref="popover">
        <div ref="contentWrapper" class="content-wrapper" v-if="visible" :class="[{[`position-${position}`]:true},popClassName]">
            <slot name="content" :close="close"></slot>
        </div>
        <span ref="triggerWrapper" class="trigger-wrapper">
            <slot></slot>
        </span>
    </div>
</template>

<script>
  export default {
    name: "f-popover"
    , data() {
      return {visible: false}
    }
    , mounted() {
      if (this.trigger === 'click') {
        this.$refs.popover.addEventListener('click', this.onClick);
      } else {
        this.$refs.popover.addEventListener('mouseenter', this.open);
        //TODO 延迟隐藏 200ms才生效
        this.$refs.popover.addEventListener('mouseleave', this.close);
      }
    }
    //destroyed 是没有this的？
    , beforeDestroy() {
      if (this.trigger === 'click') {
        this.$refs.popover.removeEventListener('click', this.onClick);
      } else {
        this.$refs.popover.removeEventListener('mouseenter', this.open);
        this.$refs.popover.removeEventListener('mouseleave', this.close);
      }
    }
    , computed: {
      openEvent() {
        if (this.trigger === 'click') {
          return 'click';
        } else {
          return 'mouseenter';
        }
      }
      , closeEvent() {
        if (this.trigger === 'click') {
          return 'click';
        } else {
          return 'mouseleave';
        }
      }
    }
    , props: {
      position: {
        type: String
        , default: 'top'
        , validator(value) {
          return ['top', 'bottom', 'left', 'right'].indexOf(value) >= 0;
        }
      }
      , trigger: {
        type: String
        , default: 'click'
        , validator(value) {
          return ['click', 'hover'].indexOf(value) >= 0;
        }
      }
      ,popClassName:{
        type:String
      }
      ,container:{
        type:Object
      }
    }
    , methods: {
      positionContent() {
        const {contentWrapper, triggerWrapper} = this.$refs;
        // (this.container||document.body).appendChild(contentWrapper);
        document.body.appendChild(contentWrapper);
        const {width, height, top, left} = triggerWrapper.getBoundingClientRect();
        const {height: height2} = contentWrapper.getBoundingClientRect();
        let positions = {
          top: {
            top: top + window.scrollY
            , left: left + window.scrollX
          }
          , bottom: {
            top: top + height + window.scrollY
            , left: left + window.scrollX
          }
          , left: {
            top: top + window.scrollY + (height - height2) / 2
            , left: left + window.scrollX
          }
          , right: {
            top: top + window.scrollY + (height - height2) / 2
            , left: left + window.scrollX + width
          }
        };
        contentWrapper.style.left = positions[this.position].left + 'px';
        contentWrapper.style.top = positions[this.position].top + 'px';
      },
      onClickDocument(e) {
        if (this.$refs.contentWrapper && this.$refs.contentWrapper.contains(e.target)) {return;}
        this.close();
      },
      open() {
        this.visible = true;
        setTimeout(() => {
          this.positionContent();
          //此时我们正处于一个时间中 在这里进行监听 小心冒泡，故这里使用了setTimeout，在冒泡完才执行
          document.addEventListener('click', this.onClickDocument); //理论上这个this 是document，但vue貌似帮我们改了
        }, 0);
      },
      close() {
        this.visible = false;
        document.removeEventListener('click', this.onClickDocument);
        console.log('关闭')
      },
      onClick(ev) {
        if (this.$refs.triggerWrapper.contains(ev.target)) {
          if (this.visible === true) {
            this.close();
          } else {
            this.open();
          }
        }
      }
    }

  }
</script>

<style lang="scss">
    $border-color: #333;
    $border-radius: 4px;
    .popover {
        display: inline-block;
        vertical-align: top;
        position: relative;
        .trigger-wrapper {
            display: inline-block;
        }
    }
    .content-wrapper {
        position: absolute;
        border: 1px solid $border-color;
        border-radius: $border-radius;
        /*box-shadow: 0 0 3px rgba(0, 0, 0, .5);*/

        /*这样就不会存在倒三角没有阴影的问题*/
        filter: drop-shadow(0 1px 1px rgba(0, 0, 0, .5));
        background: white;

        padding: .5em 1em;
        max-width: 20em;
        word-break: break-all;
        &::before, &::after {
            content: '';
            display: block;
            border: 10px solid transparent;
            width: 0px;
            height: 0px;
            position: absolute;
        }
        &.position-top {
            transform: translateY(-100%);
            margin-top: -10px;
            &::before, &::after {
                left: 10px;
            }
            &::before {
                border-bottom: none;
                border-top-color: black;
                top: 100%;
            }
            &::after {
                border-bottom: none;
                border-top-color: white;
                top: calc(100% - 1px);
            }
        }
        &.position-bottom {
            margin-top: 10px;
            &::before, &::after {
                left: 10px;
            }
            &::before {
                border-top: none;
                border-bottom-color: black;
                bottom: 100%;
            }
            &::after {
                border-top: none;
                border-bottom-color: white;
                bottom: calc(100% - 1px);
            }
        }
        &.position-left {
            transform: translateX(-100%);
            margin-left: -10px;
            &::before, &::after {
                top: 50%;
                transform: translateY(-50%);
            }
            &::before {
                border-right: none;
                border-left-color: black;
                left: 100%;
            }
            &::after {
                border-right: none;
                border-left-color: white;
                left: calc(100% - 1px);
            }
        }
        &.position-right {
            margin-left: 10px;
            &::before, &::after {
                top: 50%;
                transform: translateY(-50%);
            }
            &::before {
                border-left: none;
                border-right-color: black;
                right: 100%;
            }
            &::after {
                border-left: none;
                border-right-color: white;
                right: calc(100% - 1px);
            }
        }
    }
</style>
